/*
 * Copyright 2011 Angel Sanadinov
 *
 * This file is part of VBox WMI.
 *
 * VBox WMI is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VBox WMI is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with VBox WMI.  If not, see <http://www.gnu.org/licenses/>.
 */

package Beans.Responses.DataRetrievalComponents;

import Utilities.Functions;
import com.sun.xml.ws.commons.virtualbox_3_2.ISnapshot;
import java.util.ArrayList;
import java.util.Date;

/**
 * This class represents machine snapshot(s) data, when retrieved from the system.
 *
 * @author Angel Sanadinov
 */
public class MachineSnapshotDataComponent extends DataRetrievalComponent
{
    private String machineId;           //the snapshot's parent machine id
    private String snapshotId;          //snapshot id
    private String name;                //snapshot name
    private String description;         //snapshot description
    private Date timeStamp;             //snapshot timestamp
    private boolean isOnline;           //denotes whether the snapshot is online or not
    private boolean isCurrentSnapshot;  //denotes whether this snapshot is the current one
    private String parentId;            //the snapshot's parent snapshot id, if available
    private ArrayList<MachineSnapshotDataComponent> children; //child snapshots, if available

    /**
     * Constructs the snapshot data component with the specified data.
     *
     * @param snapshot the snapshot data, provided by the VirtualBox server
     */
    public MachineSnapshotDataComponent(ISnapshot snapshot)
    {
        this.machineId = snapshot.getMachine().getId();
        this.snapshotId = snapshot.getId();
        this.name = snapshot.getName();
        this.description = snapshot.getDescription();
        this.timeStamp = new Date(snapshot.getTimeStamp());
        this.isOnline = snapshot.getOnline();
        this.isCurrentSnapshot = false;

        if(snapshot.getParent() != null)
            this.parentId = snapshot.getParent().getId();
        else
            this.parentId = null;

        if(snapshot.getChildren() != null)
        {
            //builds all child snaphots
            this.children = new ArrayList<MachineSnapshotDataComponent>(snapshot.getChildren().size());
            for(ISnapshot child : snapshot.getChildren())
                this.children.add(new MachineSnapshotDataComponent(child));
        }
        else
            this.children = null;
    }

    /**
     * Retrieves the UUID of the snapshot's machine.
     *
     * @return the machine UUID
     */
    public String getMachineId()
    {
        return machineId;
    }

    /**
     * Retrieves the UUID of the snapshot.
     *
     * @return the snapshot UUID
     */
    public String getSnapshotId()
    {
        return snapshotId;
    }

    /**
     * Retrieves the name of the snapshot.
     *
     * @return the snapshot name
     */
    public String getName()
    {
        return name;
    }

    /**
     * Retrieves the description of the snapshot.
     *
     * @return the snapshot description
     */
    public String getDescription()
    {
        return description;
    }

    /**
     * Retrieves the data on which the snapshot was taken.
     *
     * @return the snapshot timestamp
     */
    public Date getTimeStamp()
    {
        return timeStamp;
    }

    /**
     * Returns whether this is an online or an offline snapshot.
     *
     * @return <code>true</code> if the snapshot is online or <code>false</code> if it is not
     */
    public boolean isOnline()
    {
        return isOnline;
    }

    /**
     * Returns whether this snapshot is the snapshot currently used by the virtual machine.
     *
     * @return <code>true</code> if this is the current snapshot, or <code>false</code>
     *         if it is not
     */
    public boolean isCurrentSnapshot()
    {
        return isCurrentSnapshot;
    }

    /**
     * Retrieves the UUID of this snapshot's parent.
     *
     * @return the parent snapshot UUID or <code>null</code> if there is no parent
     */
    public String getParentId()
    {
        return parentId;
    }

    /**
     * Retrieves the list of this snapshot's children.
     *
     * @return the children list or <code>null</code> if there are no child snapshots
     */
    public ArrayList<MachineSnapshotDataComponent> getChildren()
    {
        return children;
    }

    /**
     * Sets the current snapshot flag. <br><br>
     *
     * This method recursively goes through the whole snapshots tree and sets
     * the current snapshot flag on the appropriate snapshot.
     *
     * @param currentSnapshotId the UUID of the machine's current snapshot
     * @return <code>true</code> if the current snapshot flag was set or
     *         <code>false</code> otherwise
     */
    public boolean setCurrentSnapshot(String currentSnapshotId)
    {
        if(snapshotId.equals(currentSnapshotId))
        {
            isCurrentSnapshot = true;
            return true;
        }
        else if(children != null)
        {
            for(MachineSnapshotDataComponent currentChild : children)
            {
                if(currentChild.setCurrentSnapshot(currentSnapshotId))
                    return true;
                else
                    ;
            }
        }
        else
            ;

        return false;
    }

    /**
     * Checks if all child snapshots are valid.
     *
     * @return <code>true</code> if the children are valid or <code>false</code> 
     *         if an invalid child was encountered
     */
    private boolean areChildrenValid()
    {
        if(children != null)
        {
            for(MachineSnapshotDataComponent currentSnapshot : children)
            {
                if(!currentSnapshot.isValid())
                    return false;
                else
                    ;
            }
        }
        else
            ;

        return true;
    }

    @Override
    public boolean isValid()
    {
        if(Functions.isUUIDValid(snapshotId) && name != null && areChildrenValid()
                && (parentId == null || Functions.isUUIDValid(parentId)))
            return true;
        else
            return false;
    }
}
